package vno.fux.utils
{
	import com.mosesSupposes.bitmap.InteractivePNG;
	
	import flash.display.Bitmap;
	import flash.display.Sprite;

	/**
	 * 负责逐帧动画显示的基本类。
	 * 其原理是存储一个动画位图数组，通过在一个FRAME_ENTER事件的处理函数中调用update方法，以设定的间隔将数组中的每帧图像依次呈现。
	 **/
	public class BaseAnimation extends Sprite
	{
		private var _animeArry:Array;			//动画序列图数组
		private var _frameNum:int;				//动画序列图的位图数量
		private var _currentFrame:Bitmap;		//当前正在显示的动画位图
		private var _currentIndex:int = 0;		//当前正在显示的动画位图在序列图数组中的索引
		private var _isLoop:Boolean = false;	//动画是否循环
		private var _isPlaying:Boolean = false;	//动画是否播放
		private var _frameRate:int;				//跳帧数，即每过多少舞台帧本动画呈现下一帧
		private var _frameCounter:int = 0;
		private var _isReverse:Boolean = false;
		/**
		 * 创建一个新的动画显示对象
		 * @param animArr 存储有动画位图序列的一维数组
		 * @param frameRate 跳帧数设定，默认为1，即每次舞台刷新动画都更新一帧
		 * */
		//every operater should consider both reserver and unreserver
		public function BaseAnimation(animArr_:Array,  frameRate_:int = 1)
		{
			if(animArr_.length == 0)
			{
				throw new Error(typeof(BaseAnimation) + ":no animArry content!");
			}
			_currentFrame = animArr_[0];
			addChild(_currentFrame);
			_animeArry = animArr_;
			_frameNum = animArr_.length;
			_frameRate = frameRate_;
		}

		public function get frameRate():int
		{
			return _frameRate;
		}
		public function set frameRate(frameRate:int):void
		{
			_frameRate = frameRate;
		}
		public function get reverse():Boolean
		{
			return _isReverse;
		}
		public function set reverse(value:Boolean):void
		{
			_isReverse = value;
			if(reverse)
			{
				_frameCounter = (_frameNum-1)*_frameRate;
				_currentIndex = _frameNum-1;
			}
			else
			{
				_frameCounter = 0;
				_currentIndex = 0;
			}
		}
		/**
		 * 动画的刷新方法，根据目前的帧数，动画的循环及播放状态决定对象接下来的显示内容
		 * */
		public function update():void//fux：刷新机制有待改善
		{
			if(!_isReverse)
			{
				_frameCounter += 1;
				if(_frameCounter%_frameRate > 0)
				{
					return;
				}
				if(!_isPlaying)
				{
					return;
				}
				_currentFrame = _animeArry[_currentIndex];
				removeChildren();
				addChild(_currentFrame);
				_currentIndex += 1;
				if(_currentIndex > _frameNum-1)
				{
					_isPlaying = _isLoop;
					_frameCounter = 0;
					_currentIndex = 0;
				}
			}
			else
			{
				_frameCounter -= 1;
				if((_frameNum - _frameCounter+1)%_frameRate != 0)
				{
					return;
				}
				if(!_isPlaying)
				{
					return;
				}
				_currentFrame = _animeArry[_currentIndex];
				removeChildren();
				addChild(_currentFrame);
				_currentIndex -= 1;
				if(_currentIndex < 0)
				{
					_isPlaying = _isLoop;
					_frameCounter = (_frameNum-1)*_frameRate;
					_currentIndex = _frameNum-1;
				}
			}

		}
		public function get loop():Boolean
		{
			return _isLoop;
		}
		
		public function set loop(setting:Boolean):void
		{
			_isLoop = setting;
		}
		
		public function play():void
		{
			_isPlaying = true;
		}
		public function isPlaying():Boolean
		{
			return _isPlaying;
		}
		public function reset():void
		{			
			if(!_isReverse)
			{
				_frameCounter = 0;
				_currentFrame = _animeArry[0];
				removeChildren();
				addChild(_currentFrame);
				//trace("reset");
			}
			else
			{
				_frameCounter = (_frameNum-1)*_frameRate;
				_currentFrame = _animeArry[_frameNum-1];
				removeChildren();
				addChild(_currentFrame);
			}
		}
		public function stop():void
		{
			reset();
			_isPlaying = false;
		}
	}
}